package com.roubsite.cloud.security.filter;

import com.alibaba.fastjson2.JSONObject;
import com.roubsite.cloud.common.bean.Result;
import com.roubsite.cloud.common.bean.enums.UserStatusCodeEnum;
import com.roubsite.cloud.security.utils.TokenUtil;
import com.roubsite.cloud.common.request.SecurityRequest;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Component
public class SecurityFilter implements WebFilter {
    Logger log = LoggerFactory.getLogger(SecurityFilter.class);
    @Resource
    TokenUtil tokenUtil;
    @Value("${security.noFilter}")
    private String noFilter;

    @Value("${security.loginUrl}")
    private String LOGIN_URL;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        String path = request.getURI().getPath();
        if (LOGIN_URL.equals(path)) {
            return chain.filter(exchange);
        }
        String[] noFilterPaths = noFilter.split(",");
        PathMatcher pathMatcher = new AntPathMatcher();
        boolean doNotCheckThisUrl = false;
        for (String p : noFilterPaths) {
            if (StringUtils.isNotEmpty(p) && pathMatcher.match(p, path)) {
                log.debug("security check: Skip authorization check for the current URL.{}", path);
                doNotCheckThisUrl = true;
                break;
            }
        }
        if (doNotCheckThisUrl) {
            return chain.filter(exchange);
        }
        HttpHeaders httpHeaders = request.getHeaders();
        String token = httpHeaders.getFirst("Authorization");
        if (StringUtils.isEmpty(token)) {
            return chain.filter(exchange);
        }
        token = token.substring("Bearer ".length());
        String msg = tokenUtil.verifyToken(token);
        if (msg == null) {//msg为null的时候是认证并且鉴权成功了
            SecurityRequest securityRequest = new SecurityRequest(request);
            securityRequest.setToken(token);
            ServerWebExchange serverWebExchange = exchange.mutate().request(securityRequest).build();
            log.debug("security check: {}", "Authorization successful.");

            return chain.filter(serverWebExchange);
        }
        log.debug("security check: {}", "Access denied.");
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory dataBufferFactory = response.bufferFactory();
        Result result = new Result(UserStatusCodeEnum.TOKEN_EXPIRED);
//        responseResult.setCode(ResponseCodeEnums.TOKEN_EXP);
//        responseResult.setMsg(msg);
        DataBuffer dataBuffer = dataBufferFactory.wrap(JSONObject.toJSONString(result).getBytes());
        response.setRawStatusCode(401);
        return response.writeWith(Mono.just(dataBuffer));
    }
}
